#ifndef PURPLE_PLUGINS
# define PURPLE_PLUGINS
#endif

#include "plugin.h"
#include "pluginpref.h"
#include "prefs.h"
#include "version.h"
#include "account.h"
#include "conversation.h"
#include "debug.h"
#include "signals.h"
#include "status.h"
#include "privacy.h"
#include "sslconn.h"
#include "string.h"
#include <time.h>

#define GSMS_HOST  "www.google.com"
#define LOGIN_PATH "/accounts/ClientLogin"
#define FEED_PREF  "http://www.google.com/calendar/feeds/"
#define FEED_SUFF  "/private/full"
#define POST_EMAIL "source=gsms&Email="
#define POST_PASS  "&accountType=HOSTED_OR_GOOGLE&service=cl&Passwd="

typedef struct _GsmsConnection GsmsConnection;
/* Sending stages */
typedef enum {
  GSMS_IDLE,
  GSMS_AUTHENTICATING,
  GSMS_SENDING
} GsmsState;

GsmsState state = GSMS_IDLE;


struct _GsmsConnection {
  char *host;
  int port;
  void *datap;
  int fd;
  int inpa;
  PurpleProxyConnectData *connect_data;
};

/* Struct for collecting data */
struct _GsmsData {
  PurpleAccount *account;
  int gtk_warn;
  int gtk_info;
  char *name;
  char *name_enc;
  char *pass;
  char *text;
  char *http_fields;
  char *feed_url;
  char *feed_suffix;
  char *token;
};

typedef struct _GsmsData GsmsData;

/* Data from received http packet */
struct _HttpPacket {
  int resp_code;
  char *resp_string;
  char **parms;
  char *body;
};

typedef struct _HttpPacket HttpPacket;

PurplePlugin *gsms_plugin = NULL;
guint gsms_timer_handle;
int timer = 0;
char *chats;

static void
gsms_print_warn(GsmsData *gd, char *msg) {
  if (gd->gtk_warn)
    purple_notify_message(gsms_plugin, PURPLE_NOTIFY_MSG_WARNING,
        "gSMS warning", msg, NULL, NULL, NULL);
  purple_debug_warning("gsms","%s\n", msg);
}

static void
gsms_print_info(GsmsData *gd, char *msg) {
  if (gd->gtk_info)
    purple_notify_message(gsms_plugin, PURPLE_NOTIFY_MSG_INFO,
        "gSMS info", msg, NULL, NULL, NULL);
  purple_debug_info("gsms", "%s\n", msg);
}

/*
 * Convenience method for freeing HttpPacket
 */
static void
gsms_free_httppacket(HttpPacket *hp) {
  free(hp->parms);
  free(hp->body);
  free(hp);
}

/*
 * Create google calendar xml entry
 */
static char* 
gsms_create_entry(GsmsData *gd) {
  char buffer[32];
  char *cal;
  time_t curtime = time(NULL);
  struct tm *loctime = localtime(&curtime);
  GString *from, *to;
#ifdef _WIN32
  GString *tz_offset;
  int tmp, off;

  off = mktime(loctime) - mktime(gmtime(&curtime));
#endif
  
#ifndef _WIN32
  loctime->tm_min = loctime->tm_min + 7;
  mktime(loctime);

  strftime (buffer, 32, "%Y-%m-%dT%H:%M:%S.000%z", loctime);
  from = g_string_new(strdup(buffer));
  g_string_insert_c(from, from->len - 2, ':');

  loctime->tm_min = loctime->tm_min + 5;
  mktime(loctime);
  
  strftime (buffer, 32, "%Y-%m-%dT%H:%M:%S.000%z", loctime);
  to = g_string_new(strdup(buffer));
  g_string_insert_c(to, to->len - 2, ':');
#else
  curtime = time(NULL);
  loctime = localtime(&curtime);
  loctime->tm_min = loctime->tm_min + 7;
  mktime(loctime);
  
  strftime (buffer, 32, "%Y-%m-%dT%H:%M:%S.000", loctime);
  from = g_string_new(strdup(buffer));
  purple_debug_info("gsms", "From: %s", from->str);

  loctime->tm_min = loctime->tm_min + 13;
  mktime(loctime);

  strftime (buffer, 32, "%Y-%m-%dT%H:%M:%S.000", loctime);
  to = g_string_new(strdup(buffer));
  purple_debug_info("gsms", "To: %s", to->str);
  
  tz_offset = g_string_new("");
  if (off < 0) {
    g_string_append(tz_offset, "-");
  } else {
    g_string_append(tz_offset, "+");
  }
  
  tmp = off / 3600;
  if (tmp < 10) {
    g_string_append(tz_offset, "0");
  }
  g_string_append_printf(tz_offset, "%d:", tmp);
  
  tmp = off % 3600;
  tmp /= 60;
  if (tmp < 10) {
    g_string_append(tz_offset, "0");
  }
  g_string_append_printf(tz_offset, "%d", tmp);
  
  g_string_append(from, strdup(tz_offset->str));
  g_string_append(to, strdup(tz_offset->str));

  g_string_free(tz_offset, TRUE);
#endif
  
  cal =(char*)malloc(2048*sizeof(char));
  sprintf(cal, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
      "<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' ",
        "xmlns:gAcl='http://schemas.google.com/acl/2007' ",
        "xmlns:gCal='http://schemas.google.com/gCal/2005' ",
        "xmlns:gd='http://schemas.google.com/g/2005'>",
          "<atom:category scheme='http://schemas.google.com/g/2005#kind' ",
            "term='http://schemas.google.com/g/2005#event'></atom:category>",
           "<atom:title type='text'>Chats from: ", gd->text, "</atom:title>",
           "<atom:content type='text'>", "Created by: gSms - Pidgin plugin", "</atom:content>",
           "<gCal:quickadd value='", "false", "'></gCal:quickadd>",
           "<gd:when ",
             "startTime='",from->str,"' ",
             "endTime='",to->str,"'>",
               "<gd:reminder minutes='5' method='sms'></gd:reminder>",
           "</gd:when>",
       "</atom:entry>\0");
  
  g_string_free(from, TRUE);
  g_string_free(to, TRUE);
  
  return cal;
}

/*
 * Parses received http packet
 */
static HttpPacket*
gsms_parse_http_packet(char *packet) {
  GString *p;
  HttpPacket *hp = (HttpPacket*)malloc(sizeof(HttpPacket));
  char *token;
  int blen, i = 0;
  
  token = strtok(strdup(packet), " ");
  hp->resp_code = atoi(strtok(NULL, " "));
  hp->resp_string = strtok(NULL, "\r");
  
  p = g_string_new(strstr(strdup(packet), "\r\n\r\n"));
  blen = p->len;
  g_string_erase(p, 0, 4);
  hp->body = strdup(p->str);
  g_string_free(p, TRUE);

  hp->parms = (char**)malloc(10*sizeof(char*));
  p = g_string_new(strdup(packet));
  token = strtok(strdup(p->str), "\n");
  while ((token = strtok(NULL, "\n")) != NULL) 
  {
    token[strlen(token) - 1] = '\0';
    if (!strcmp(token, "")) break;
    hp->parms[i++] = token;
  }
  
  g_string_free(p, TRUE);
  return hp;
}

/*
 * Receive plain http packet
 */
static void
gsms_receive_cb(gpointer data, gint source, PurpleInputCondition cond) {
  GsmsConnection *gc = data;
  GsmsData *gd = gc->datap;
  HttpPacket *hp;
  static char buf[4096];
  char *cal;
  int len, i = 0, moved = FALSE, tmp, cleanup = TRUE;
  GString *new_loc;
  
  /* Prevents infinite loop */
  purple_input_remove(gc->inpa);
  
  /* Read packet */
  len = read(gc->fd, buf, sizeof(buf) - 1);
  buf[len] = '\0';
  hp = gsms_parse_http_packet(buf);
  purple_debug_info("gsms", "Received HTTP packet: %s", hp->body);
  
  /* Moved */
  if (hp->resp_code == 302) {
    /* Find redirected url in packet parameters */
    while (hp->parms[i] != NULL) {
      if (g_str_has_prefix(hp->parms[i++], "Location:")) {
        new_loc = g_string_new(hp->parms[i-1]);
        g_string_erase(new_loc, 0, strlen("Location: "));
        
        /* Strip protocol declaration from redirected url */
        if (g_str_has_prefix(new_loc->str, "http://")) {
          g_string_erase(new_loc, 0, strlen("http://"));
        /* Shouldn't happen... but who knows */
        } else {
          g_string_erase(new_loc, 0, strlen("https://"));
        }
        
        /* Strip host name from redirected url */
        g_string_erase(new_loc, 0, strlen(GSMS_HOST));
        free(gd->feed_url);
        gd->feed_url = strdup(new_loc->str);
        g_string_free(new_loc, TRUE);
        moved = TRUE;
        break;
      }
    }
    
    /* Redirected url parsed succesfully */
    if (moved) {
      cal = gsms_create_entry(gd);
      
      sprintf(buf, "%s%s%s%s%s%s%s%s%s%s%s%d%s%s%s%s", 
          "POST ", gd->feed_url, " HTTP/1.1\r\n",
          "Host: ", GSMS_HOST, "\r\n",
          "Accept: */*\r\n",
          "Authorization: GoogleLogin auth=", gd->token, "\r\n",
          "Content-Length: ", strlen(cal), "\r\n",
          "Content-Type: application/atom+xml;charset=UTF-8\r\n\r\n",
          cal, "\r\n\0");
      free(cal);
      
      tmp = write(gc->fd, buf, strlen(buf));
      gc->inpa = purple_input_add(gc->fd, PURPLE_INPUT_READ, (void*)gsms_receive_cb, gc);
      purple_debug_info("gsms", "Sent HTTP packet: %s", buf);
      cleanup = FALSE;
    /* Shouldn't happen... exit */
    } else {
      /* NOOP */
    }
  /* Calendar entry created */
  } else if (hp->resp_code == 201) {
    gsms_print_info(gd, "Calendar entry created.");
  /* Unexpected response codes */  
  } else {
    gsms_print_warn(gd, "Sending calendar failed.");
  }
  
  gsms_free_httppacket(hp);

  if (cleanup) {
    free(gd->feed_url);
    free(gd->text);
    free(gd->token);
    free(gd);
    
    close(gc->fd);
    g_free(gc->host);
    g_free(gc);
    
    state = GSMS_IDLE;
  }
}

/*
 * Login to calendar server
 */
static void
gsms_login(GsmsConnection *gc)
{
  GsmsData *gd = gc->datap;
  static char buf[4096];
  int tmp;
  
  sprintf(buf, "%s%s%s%s%s%s%s%s%s%s%s%s", 
      "POST ", gd->feed_url, " HTTP/1.1\r\n",
      "Host: ", GSMS_HOST, "\r\n",
      "Accept: */*\r\n",
      "Authorization: GoogleLogin auth=", gd->token, "\r\n",
      "Content-Length: 0\r\n",
      "Content-Type: application/atom+xml;charset=UTF-8\r\n\r\n\r\n");
  
  purple_debug_info("gsms", "Sending packet\n");
  tmp = write(gc->fd, buf, strlen(buf));
  gc->inpa = purple_input_add(gc->fd, PURPLE_INPUT_READ, (void*)gsms_receive_cb, gc);
  purple_debug_info("gsms", "Sent HTTP packet: %s", buf);
}

/*
 * Called when plain connection to server is opened
 */
static void
gsms_connect_cb(gpointer data, gint source, const gchar *error) {
  GsmsConnection *gc = data;
  GsmsData *gd = gc->datap;
  gc->connect_data = NULL;

  if (source < 0) {
    if (gc->connect_data != NULL)
      purple_proxy_connect_cancel(gc->connect_data);

    if (gc->inpa > 0)
      purple_input_remove(gc->inpa);

    if (gc->fd >= 0)
      close(gc->fd);
    
    free(gd->feed_url);
    free(gd->text);
    free(gd->token);
    free(gd);
    g_free(gc->host);
    g_free(gc);
    
    state = GSMS_IDLE;
  } else {
    gc->fd = source;
    gsms_login(gc);
  }
}

/*
 * Start connecting to google calendar service
 */
static void 
gsms_begin_conversation_procedure(GsmsData *gd) {
  GsmsConnection *gc = g_new0(GsmsConnection, 1);
  gc->fd              = -1;
  gc->host            = g_strdup(GSMS_HOST);
  gc->port            = 80;
  gc->datap = (gpointer)gd;
  gc->connect_data    =
    purple_proxy_connect(NULL, gd->account, GSMS_HOST, 80, gsms_connect_cb, gc);

  if (gc->connect_data == NULL) {
    free(gd->feed_url);
    free(gd->text);
    free(gd->token);
    free(gd);
    g_free(gc->host);
    g_free(gc);
    state = GSMS_IDLE;
  }
}

/*
 * Receive ssl http packet
 */
static void
gsms_ssl_receive_cb(gpointer data, PurpleSslConnection *gsc,
    PurpleInputCondition cond) {
  GsmsData *gd = data;
  HttpPacket *hp;
  GString *auth;
  static char buf[4096];
  int i, len = purple_ssl_read(gsc, buf, sizeof(buf) - 1);
  
  buf[len] = '\0';
  hp = gsms_parse_http_packet(buf);
  
  /* Wrong response, cleanup */
  if (hp->resp_code != 200) {
    free(gd->feed_url);
    free(gd->text);
    free(gd);
    state = GSMS_IDLE;
  /* Parse token */
  } else {
    auth = g_string_new(strstr(hp->body, "Auth="));
    g_string_erase(auth, 0, 5);
    for (i = auth->len - 1; i >= 0; i--)
      if (auth->str[i] == '\r' || auth->str[i] == '\n')
        g_string_erase(auth, i, 1);
    gd->token = g_strdup(auth->str);
    g_string_free(auth, TRUE);
    /* Token parsed */
    purple_debug_info("gsms", "Auth token received: %s\n", gd->token);

    state = GSMS_SENDING;
    gsms_begin_conversation_procedure(gd);
  }

  gsms_free_httppacket(hp);
  purple_ssl_close(gsc);
}

/*
 * Login to ssl authentication server
 */
static void
gsms_ssl_login_cb(gpointer data, PurpleSslConnection *gsc, 
    PurpleInputCondition cond) {
  GsmsData *gd = data;
  int len;
  static char buf[4096];
  char *fields = strdup(gd->http_fields);
  
  sprintf(buf, "%s%s%s%s%s%s%s%s%d%s%s%s%s", 
      "POST ", LOGIN_PATH, " HTTP/1.1\r\n",
      "Host: ", GSMS_HOST, "\r\n",
      "Accept: */*\r\n",
      "Content-Length: ", strlen(fields), "\r\n",
      "Content-Type: application/x-www-form-urlencoded\r\n\r\n",
      fields, "\r\n");
  
  free(fields);
  free(gd->http_fields);
  
  len = strlen(buf);
  
  purple_debug_info("gsms", "Sending auth packet\n");
  
  purple_ssl_write(gsc, buf, len);
  purple_ssl_input_add(gsc, gsms_ssl_receive_cb, data);
}

/*
 * Called when ssl connection to server has failed
 */
static void
gsms_ssl_fail_cb(PurpleSslConnection *gsc, PurpleSslErrorType error,
    gpointer data) {
  GsmsData *gd = data;
  GString *txt = g_string_new("Error connecting to: ");
  
  g_string_append(txt, gsc->host);
  g_string_append(txt, ":443");
  
  gsms_print_warn(data, txt->str);
  g_string_free(txt, TRUE);
  free(gd->http_fields);
  free(gd->feed_url);
  free(gd->text);
  free(gd);
  
  state = GSMS_IDLE;
}

/*
 * Start connecting to authentication server
 */
static void
gsms_begin_auth_ssl_procedure(GsmsData *data) {
  /* Procees only if ssl is enabled (required by auth process) */
  if (purple_ssl_is_supported()) {
    purple_ssl_connect(
        data->account, GSMS_HOST, 443, gsms_ssl_login_cb,
        gsms_ssl_fail_cb, data);
  /* Cleanup */
  } else {
    gsms_print_warn(data, "You don't have ssl support.");
    free(data->http_fields);
    free(data->feed_url);
    free(data->text);
    free(data);
    state = GSMS_IDLE;
  }
}

/*
 * Called when chat is received
 */
static void
gsms_received_im_cb (PurpleAccount *acct, const char *name, void *data) {
  GString *tmp;
  PurpleBuddy *buddy;
  
  if (!purple_find_buddy(acct, strdup(name))) {
    purple_debug_info("gsms", "Not a buddy, doing nothing\n");
  } else if(FALSE == purple_privacy_check(acct, name)) {
    purple_debug_info("gsms", "user %s is blocked\n", name);
  }
  
  buddy = purple_find_buddy(acct, strdup(name));
  
  if (chats == NULL) {
    tmp = g_string_new("");
  } else {
    if (strstr(chats, buddy->alias) != NULL) return;
    tmp = g_string_new(strdup(chats));
    g_string_append(tmp, ", ");
  }
  
  g_string_append(tmp, strdup(buddy->alias));

  chats = strdup(tmp->str);
  g_string_free(tmp, TRUE);
}

/*
 * Called when status has changed
 */
static void
gsms_status_changed_cb (PurpleAccount *acct, const char *name, void *data) {

  //TODO
  purple_debug_info("gsms", "Status changed!\n");

}

static PurplePluginPrefFrame *
gsms_plugin_preferences(PurplePlugin *plugin) {
  PurplePluginPrefFrame *frame;
  PurplePluginPref *ppref;
  
  frame = purple_plugin_pref_frame_new();

  ppref = purple_plugin_pref_new_with_label("Configuration");
  purple_plugin_pref_frame_add(frame, ppref);

  ppref = purple_plugin_pref_new_with_name_and_label(
                "/plugins/core/gsms/uname",
                "Gmail account");
  purple_plugin_pref_frame_add(frame, ppref);

  ppref = purple_plugin_pref_new_with_name_and_label(
                "/plugins/core/gsms/pass",
                "Password");
  purple_plugin_pref_set_masked(ppref, TRUE);
  purple_plugin_pref_frame_add(frame, ppref);
  
  ppref = purple_plugin_pref_new_with_name_and_label(
      "/plugins/core/gsms/coll_time", 
      "Timeout (in minutes)");
  purple_plugin_pref_set_bounds(ppref, 1, 60*24);
  purple_plugin_pref_frame_add(frame, ppref);
  
  ppref = purple_plugin_pref_new_with_label("Notification popups");
  purple_plugin_pref_frame_add(frame, ppref);

  ppref = purple_plugin_pref_new_with_name_and_label(
                  "/plugins/core/gsms/info",
                  "Informations");
  purple_plugin_pref_frame_add(frame, ppref);
  
  ppref = purple_plugin_pref_new_with_name_and_label(
                  "/plugins/core/gsms/warn",
                  "Warnings");
  purple_plugin_pref_frame_add(frame, ppref);

  ppref = purple_plugin_pref_new_with_label("Advanced preferences");
  purple_plugin_pref_frame_add(frame, ppref);
  
  ppref = purple_plugin_pref_new_with_name_and_label(
                "/plugins/core/gsms/feed_suff",
                "Calendar feed path");
  purple_plugin_pref_frame_add(frame, ppref);

  return frame;
}

static void
gsms_collect_user_data(GsmsData *gd) {
  gd->name = strdup(purple_prefs_get_string("/plugins/core/gsms/uname"));
  gd->pass = strdup(purple_prefs_get_string("/plugins/core/gsms/pass"));
  gd->gtk_warn = purple_prefs_get_bool("/plugins/core/gsms/warn");
  gd->gtk_info = purple_prefs_get_bool("/plugins/core/gsms/info");
  gd->feed_suffix = strdup(purple_prefs_get_string("/plugins/core/gsms/feed_suff"));
}

static gboolean
gsms_timer_cb(gpointer data) {
  /* Start variables declaration */
  GString *url_feed, *html_fields;
  GsmsData *gd = (GsmsData*)malloc(sizeof(GsmsData));
  GList *accts;
  int cleanup = TRUE;
  int interval = purple_prefs_get_int("/plugins/core/gsms/coll_time");
  /* End variables declaration */
  
  /* Close any opened notifications */
  purple_notify_close_with_handle(gsms_plugin);
  
  /* Init gsmsdata*/
  gsms_collect_user_data(gd);

  /* Get all active accounts */
  accts = purple_accounts_get_all_active();
  
  /* Get first active account and check if its status is available */
  if (purple_status_is_available(
        purple_account_get_active_status(accts->data))) {
    purple_debug_info("gsms", "Status is available, doing nothing.\n");
    /* Reset timer and collected chats */
    timer = 0;
    if (chats != NULL) {
      free(chats);
      chats = NULL;
    }
  } else {
    /* Increment timer by one minute */
    timer += 1;

    /* Check if it's time to send collected data */
    if (interval >= timer) {
      purple_debug_info("gsms", "Trying to send calendar entry.\n");
      /* This shouldn't happen. Previous processes should allways set state to IDLE */
      if (state != GSMS_IDLE) {
        gsms_print_warn(gd, "Previous sending process is not complete.");
      /* No chats received during collection period */
      } else if (chats == NULL) {
        purple_debug_info("gsms", "No chats collected."); 
        /* Empty mail */
      } else if (strcmp(gd->name, "") == 0) {
        gsms_print_warn(gd, "No gmail account used, doing nothing.");
        /* Empty pass */
      } else if (strcmp(gd->pass, "") == 0) {
        gsms_print_warn(gd, "No password used, doing nothing.");
        /* Mail is not valid */
      } else if (!purple_email_is_valid(gd->name)) {
        gsms_print_warn(gd, "Given mail is invalid.");
        /* Empty feed suffix */
      } else if (strcmp(gd->feed_suffix, "") == 0) {
        gsms_print_warn(gd, "No feed path, doing nothing.");
        /* All ok, proceed */
      } else {
        /* Main processing is reached, so GsmsData must not be freed */
        cleanup = FALSE;
        
        /* Current state */
        state = GSMS_AUTHENTICATING;
        
        gd->account = accts->data;
        gd->text = strdup(chats);
        gd->name_enc = strdup(purple_url_encode(gd->name));
        free(gd->name);
        
        /* Create feed url */
        url_feed = g_string_new(FEED_PREF);
        g_string_append(url_feed, gd->name_enc);
        g_string_append(url_feed, gd->feed_suffix);
        gd->feed_url = strdup(url_feed->str);
        g_string_free(url_feed, TRUE);
        free(gd->feed_suffix);

        /* Create post fields */
        html_fields = g_string_new(POST_EMAIL);
        g_string_append(html_fields, gd->name_enc);
        g_string_append(html_fields, POST_PASS);
        g_string_append(html_fields, gd->pass);
        gd->http_fields = strdup(html_fields->str);
        g_string_free(html_fields, TRUE);
        free(gd->pass);
        free(gd->name_enc);
        
        /*
         * GsmsData now contains:
         * http_fields - must free after use
         * feed_url    - must free after use
         * text        - must free after use
         * 
         * account     - never free
         * gtk_warn
         * gtk_info
         */
        
        /* Begin authentication */
        gsms_begin_auth_ssl_procedure(gd);
        
        /* Empty collected chat list */
        free(chats);
        chats = NULL;
      }
      
      /* GsmsData can be freed because it isn't used any further */
      if (cleanup) {
        free(gd->name);
        free(gd->pass);
        free(gd);
      }
      
      /* Reset timer */
      timer = 0;
    }
  }
  
  /* Continue timer. Timer is stopped in gsms_unload function */
  return TRUE;
}

static gboolean
gsms_load(PurplePlugin *plugin) {
  purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", plugin,
          PURPLE_CALLBACK(gsms_received_im_cb), NULL);
  purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", plugin,
          PURPLE_CALLBACK(gsms_status_changed_cb), NULL);
  
  gsms_timer_handle = purple_timeout_add_seconds(60, gsms_timer_cb, NULL);
  gsms_plugin = plugin;
  
  return TRUE;
}

static gboolean
gsms_unload(PurplePlugin *plugin) {
  purple_timeout_remove(gsms_timer_handle);
  timer = 0;
  chats = NULL;
  gsms_plugin = NULL;
  return TRUE;
}

static PurplePluginUiInfo gsms_prefs_info = {
  gsms_plugin_preferences,
  0,   /* page_num (Reserved) */
  NULL, /* frame (Reserved) */
  /* Padding */
  NULL,
  NULL,
  NULL,
  NULL
};

static PurplePluginInfo gsms_info =
{
  PURPLE_PLUGIN_MAGIC,
  PURPLE_MAJOR_VERSION,
  PURPLE_MINOR_VERSION,
  PURPLE_PLUGIN_STANDARD,                             /**< type           */
  NULL,                                             /**< ui_requirement */
  0,                                                /**< flags          */
  NULL,                                             /**< dependencies   */
  PURPLE_PRIORITY_DEFAULT,                            /**< priority       */

  "core-usajusaj-gsms",
  "gSMS",
  "3.14", /* This constant is defined in version.h, but you shouldn't use it for
        your own plugins.  We use it here because it's our plugin. */

  "Google sms reminder sender",
  "Sends sms via google calendar, informing you if there were any incoming messages while you were away.",
  "Matej Usaj <gsms@usajusaj.org>", /* correct author */
  "http://gsms.usajusaj.org",


  gsms_load,
  gsms_unload,
  NULL,

  NULL,
  NULL,
  &gsms_prefs_info,            /**< prefs_info */
  NULL,
  /* padding */
  NULL,
  NULL,
  NULL,
  NULL
};

static void
gsms_init(PurplePlugin *plugin)
{
  purple_prefs_add_none("/plugins/core/gsms");
  purple_prefs_add_string("/plugins/core/gsms/uname",
              "foo.bar@gmail.com");
  purple_prefs_add_string("/plugins/core/gsms/pass", "");
  purple_prefs_add_int("/plugins/core/gsms/coll_time", 15);

  purple_prefs_add_bool("/plugins/core/gsms/info", FALSE);
  purple_prefs_add_bool("/plugins/core/gsms/warn", FALSE);

  purple_prefs_add_string("/plugins/core/gsms/feed_suff", FEED_SUFF);
}

/* 
 * TODO Search for existing gmail accounts
 * TODO Get time from the server 
 */

PURPLE_INIT_PLUGIN(ppexample, gsms_init, gsms_info)
